package com.kk.xhr.admin.biz.impl;

import com.kk.xhr.admin.biz.IAdjustSalaryBizService;
import com.kk.xhr.admin.controller.request.AdjustSalaryAddRequest;
import com.kk.xhr.admin.controller.request.AdjustSalaryModifyRequest;
import com.kk.xhr.admin.controller.vo.AdjustSalaryVO;
import com.kk.xhr.common.ErrorCodeEnum;
import com.kk.xhr.common.exception.BusinessException;
import com.kk.xhr.common.pojo.BinaryEnum;
import com.kk.xhr.model.dto.AdjustSalaryDTO;
import com.kk.xhr.model.dto.AppraiseDTO;
import com.kk.xhr.model.dto.NotificationDTO;
import com.kk.xhr.model.dto.SalaryDTO;
import com.kk.xhr.model.service.IAdjustSalaryService;
import com.kk.xhr.model.service.IAppraiseService;
import com.kk.xhr.model.service.INotificationService;
import com.kk.xhr.model.service.ISalaryService;
import com.kk.xhr.model.service.IUserService;
import com.kk.xhr.util.DateUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 调薪biz服务接口实现
 *
 * @author kkmystery
 * @version 1.0 2021/3/8
 * @since 1.0.0
 */
@Service
@RequiredArgsConstructor
public class AdjustSalaryBizServiceImpl implements IAdjustSalaryBizService {
    private final IAdjustSalaryService adjustSalaryService;
    private final ISalaryService salaryService;
    private final IUserService userService;
    private final INotificationService notificationService;
    private final IAppraiseService appraiseService;

    /**
     * {@inheritDoc}
     */
    @Override
    public List<AdjustSalaryVO> queryMine(Long userId) {
        return adjustSalaryService.queryByUserId(userId)
            .stream()
            .map(this::generateVO)
            .collect(Collectors.toList());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(AdjustSalaryAddRequest request) {
        SalaryDTO salary = salaryService.queryByUserId(request.getUserId())
            .orElseThrow(() -> new BusinessException(ErrorCodeEnum.SALARY_NOT_EXIST));
        long after = salary.getBasicSalary() + (salary.getBasicSalary() * request.getPercentage()) / 100;
        adjustSalaryService.add(AdjustSalaryDTO.builder()
            .userId(request.getUserId())
            .changeDate(DateUtil.validTime(request.getChangeDate()))
            .after(after)
            .before(salary.getBasicSalary())
            .reason(request.getReason())
            .remark(request.getRemark())
            .build());
        salaryService.modify(SalaryDTO.builder()
            .id(salary.getId())
            .basicSalary(after)
            .build());
        appraiseService.modify(AppraiseDTO.builder().id(request.getAppraiseId()).status(BinaryEnum.FALSE).build());
        notificationService.add(NotificationDTO.builder()
            .userId(request.getUserId())
            .message("鉴于考评成绩，您的薪资已做调整")
            .build());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void modify(Long id, AdjustSalaryModifyRequest request) {
        SalaryDTO salary = salaryService.queryByUserId(request.getUserId())
            .orElseThrow(() -> new BusinessException(ErrorCodeEnum.SALARY_NOT_EXIST));
        adjustSalaryService.modify(AdjustSalaryDTO.builder()
            .id(id)
            .changeDate(request.getChangeDate())
            .after(request.getAfter())
            .reason(request.getReason())
            .remark(request.getRemark())
            .build());
        if (!salary.getBasicSalary().equals(request.getAfter())) {
            salaryService.modify(SalaryDTO.builder()
                .id(salary.getId())
                .basicSalary(request.getAfter())
                .build());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean modifyStatus(Long id, BinaryEnum status) {
        return adjustSalaryService.modifyStatus(id, status);
    }

    /**
     * AdjustSalaryVO生成器
     *
     * @param dto AdjustSalaryDTO
     * @return AdjustSalaryVO
     */
    private AdjustSalaryVO generateVO(AdjustSalaryDTO dto) {
        return AdjustSalaryVO.builder()
            .id(dto.getId())
            .name(userService.queryName(dto.getUserId()))
            .after(dto.getAfter())
            .before(dto.getBefore())
            .changeDate(dto.getChangeDate())
            .reason(dto.getReason())
            .remark(dto.getRemark())
            .status(dto.getStatus())
            .build();
    }
}
